package com.easychat.redis;

import com.easychat.constants.Constants;
import com.easychat.entity.config.AppConfig;
import com.easychat.entity.dto.SysSettingDTO;
import com.easychat.entity.dto.TokenUserInfoDTO;
import com.easychat.utils.StringTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class RedisComponent {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private AppConfig appConfig;

    /**
     * 获取userId所在的服务器端口号
     * @param userId
     * @return
     */
    public String getServerPort(String userId) {
        return (String) redisTemplate.opsForValue().get(Constants.REDIS_KEY_UID2PORT + userId);
    }
    /**
     * 将userId和对应的端口号保存起来，方便消息推送时正确路由，找到联系人所在服务器对应的（mq）channel
     * @param userId
     */
    public void saveServerPort(String userId) {
        redisTemplate.opsForValue().set(Constants.REDIS_KEY_UID2PORT + userId, appConfig.getServerPort().toString(), Constants.REDIS_KEY_EXPIRES_HEART_BEAT, TimeUnit.SECONDS);
    }

    /**
     * 删除userId对应的key，代表该用户与服务器断开连接
     * @param userId
     */
    public void removeServerPort(String userId) {
        redisTemplate.delete(Constants.REDIS_KEY_UID2PORT + userId);
    }
    /**
     * 获取心跳
     * @param userId
     * @return
     */
    public Long getUserHeartBeat(String userId) {
        //return (Long) redisUtils.get(Constants.REDIS_KEY_WS_USER_HEART_BEAT + userId);
        return (Long) redisTemplate.opsForValue().get(Constants.REDIS_KEY_WS_USER_HEART_BEAT + userId);
    }

    /**
     * 储存心跳
     * @param userId
     * @return
     */
    public void saveUserHeartBeat(String userId) {
        redisTemplate.opsForValue().set(Constants.REDIS_KEY_WS_USER_HEART_BEAT + userId, System.currentTimeMillis(), Constants.REDIS_KEY_EXPIRES_HEART_BEAT, TimeUnit.SECONDS);
    }

    /**
     * 清除心跳
     * @param userId
     */
    public void cleanUserHeartBeat(String userId) {
        redisTemplate.delete(Constants.REDIS_KEY_WS_USER_HEART_BEAT + userId);
    }

    /**
     * 保存tokenUserInfoDTO
     * @param tokenUserInfoDTO
     */
    public void saveTokenUserInfoDTO(TokenUserInfoDTO tokenUserInfoDTO) {
        //通过token存tokenUserInfoDTO
        redisTemplate.opsForValue().set(Constants.REDIS_KEY_WS_TOKEN + tokenUserInfoDTO.getToken(), tokenUserInfoDTO, Constants.REDIS_TIME_1DAY * 2, TimeUnit.SECONDS);
        //通过userId存tokenUserInfoDTO的token
        redisTemplate.opsForValue().set(Constants.REDIS_KEY_WS_TOKEN_USERID + tokenUserInfoDTO.getUserId(), tokenUserInfoDTO.getToken(), Constants.REDIS_TIME_1DAY * 2, TimeUnit.SECONDS);
    }

    /**
     * 根据userId清除对应的token信息
     * @param userId
     */
    public void cleanUserTokenByUserId(String userId) {
        String token = (String) redisTemplate.opsForValue().get(Constants.REDIS_KEY_WS_TOKEN_USERID + userId);
        if (StringTools.isEmpty(token)) {
            return;
        }
        redisTemplate.delete(Constants.REDIS_KEY_WS_TOKEN + token);
    }

    /**
     * 根据token对应的key获取tokenUserInfoDTO
     * @param token
     */
    public TokenUserInfoDTO getTokenUserInfoDTO(String token) {
        TokenUserInfoDTO tokenUserInfoDTO = (TokenUserInfoDTO) redisTemplate.opsForValue().get(Constants.REDIS_KEY_WS_TOKEN + token);
        return tokenUserInfoDTO;
    }

    /**
     * 根据userId对应的token获取tokenUserInfoDTO
     * @param userId
     */
    public TokenUserInfoDTO getTokenUserInfoDTOByUserId(String userId) {
        String token = (String) redisTemplate.opsForValue().get(Constants.REDIS_KEY_WS_TOKEN_USERID + userId);
        if (StringTools.isEmpty(token)) {
            return null;
        }
        return getTokenUserInfoDTO(token);
    }

    /**
     * 获取系统设置对象
     * @return
     */
    public SysSettingDTO getSysSetting() {
        SysSettingDTO sysSettingDTO = (SysSettingDTO) redisTemplate.opsForValue().get(Constants.REDIS_KEY_SYS_SETTING);
        if (sysSettingDTO == null) {
            sysSettingDTO = new SysSettingDTO();//new的对象属性有初始值
        }
        return sysSettingDTO;
    }

    /**
     * 保存系统设置对象
     * @return
     */
    public void saveSysSetting(SysSettingDTO sysSettingDTO) {
        redisTemplate.opsForValue().set(Constants.REDIS_KEY_SYS_SETTING, sysSettingDTO);
    }

    /**
     * 删除userId对应的联系人列表
     * @param userId
     */
    public void cleanUserContact(String userId) {
        redisTemplate.delete(Constants.REDIS_KEY_USER_CONTACT + userId);
    }

    /**
     * 从userId的联系人列表中，删除contactId (count = 0：删除等于value的所有元素。)
     * @param userId
     * @param contactId
     */
    public void removeUserContact(String userId, String contactId) {
         redisTemplate.opsForList().remove(Constants.REDIS_KEY_USER_CONTACT + userId, 0, contactId);//TODO key忘记加userId了
    }
    /**
     * 保存userId对应的联系人列表
     * @param userId
     * @param contactIdList
     */
    public void saveUserContactBatch(String userId, List<String> contactIdList) {
        redisTemplate.opsForList().leftPushAll(Constants.REDIS_KEY_USER_CONTACT + userId, contactIdList);
        //设置过期时间
        redisTemplate.expire(Constants.REDIS_KEY_USER_CONTACT + userId, Constants.REDIS_TIME_1DAY * 2, TimeUnit.SECONDS);
    }

    /**
     * 保存userId对应的联系人
     * @param userId
     * @param contactId
     */
    public void saveUserContact(String userId, String contactId) {
        List<String> contactIdList = getUserContact(userId);
        if (contactIdList.contains(contactId)) {
            //联系人列表已经包含了此contactId
            return;
        }
        redisTemplate.opsForList().leftPush(Constants.REDIS_KEY_USER_CONTACT + userId, contactId);
        //设置过期时间
        redisTemplate.expire(Constants.REDIS_KEY_USER_CONTACT + userId, Constants.REDIS_TIME_1DAY * 2, TimeUnit.SECONDS);
    }

    /**
     * 获取userId对应的联系人列表
     * @param userId
     */
    public List<String> getUserContact(String userId) {
        List<String> contactIdList = redisTemplate.opsForList().range(Constants.REDIS_KEY_USER_CONTACT + userId, 0, -1);
        return contactIdList;
    }
}
